package com.sczmgk.hotline_pzh.hxim;


import android.content.Context;

import com.google.gson.Gson;
import com.hyphenate.EMCallBack;
import com.hyphenate.EMMessageListener;
import com.hyphenate.chat.EMClient;
import com.hyphenate.chat.EMConversation;
import com.hyphenate.chat.EMMessage;
import com.hyphenate.chat.EMMessageBody;
import com.sczmgk.hotline_pzh.callback.HttpFailCallback;
import com.sczmgk.hotline_pzh.callback.SimplePaserJsonCallback;
import com.sczmgk.hotline_pzh.constants.Constants;
import com.sczmgk.hotline_pzh.db.impl.ChatMsgDaoImpl;
import com.sczmgk.hotline_pzh.db.impl.NewMsgCountDaoImpl;
import com.sczmgk.hotline_pzh.db.impl.UserDaoImpl;
import com.sczmgk.hotline_pzh.entity.BaseEntity;
import com.sczmgk.hotline_pzh.entity.MessageCountBean;
import com.sczmgk.hotline_pzh.entity.User;
import com.sczmgk.hotline_pzh.httputils.MyHttp;
import com.sczmgk.hotline_pzh.jpush.UIObserver;
import com.sczmgk.hotline_pzh.sp.CacheUtils;
import com.sczmgk.hotline_pzh.utils.MyLog;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 环信测试工具类
 */
public class HxImUtils{

    private  boolean chatIsForegound = false;
    public static String toChatUsername = "renhekf_01";
    private static final String TAG = HxImUtils.class.getSimpleName();
    Context context;
    private ChatMessageComparator chatMessageComparator = new ChatMessageComparator();

    public HxImUtils(Context context) {
        super();
        this.context = context;
    }

    public  boolean isChatIsForegound() {
        return this.chatIsForegound;
    }

    /**
     *
     * @param chatIsForegound
     */
    public  void setChatIsForegound(boolean chatIsForegound) {
        this.chatIsForegound = chatIsForegound;
    }

    /**
     * 初始化广播
     */
    public void initIm() {

        registerMessageListener();

    }

    /**
     * 更新消息 (自定义消息,不存在则自动添加)
     * @param mMsg   自定义的消息
     * @param origin 调用来源
     */
//    public  void updateMsg(final ChatMsgBean mMsg,int origin){
//
//        if(mMsg == null){
//            return;
//        }
//        if(Tools.isEmpty(mMsg.getMymsgid())){
//            return;
//        }
//        MyLog.i(TAG,"--------------------updateMsg------------------------");
//        String originStr="未知   ";
//        switch (origin){
//            case 1:
//                originStr = "发送消息给环信回调  ";
//                break;
//            case 2:
//                originStr = "发送消息 -> 上传到服务器  ";
//                break;
//            case 3:
//                originStr = "重发消息给环回调";
//                break;
//            case 4:
//                originStr = "重发消息给环信 -> 上传服务器";
//                break;
//            case 5:
//                originStr = "接收到消息 -> 上传服务器";
//                break;
//        }
//
//        if(mMsg != null){
//            if(Tools.isEmpty(mMsg.getMymsgid())){
//                MyLog.e(TAG,"调用来源:  "+ originStr+ "     mymsgid   is  null ");
//            }else{
//                MyLog.d(TAG,"调用来源:  "+ originStr+ "     mymsgid: "+mMsg.getMymsgid());
//            }
//
//        }else{
//            MyLog.e(TAG,"调用来源:  "+ originStr+ "   myMsg is null");
//        }
//        String jsonStr;
//        Gson gson = new Gson();
//        jsonStr = gson.toJson(mMsg).toString();
//
//        MyHttp.requestFromJson(Constants.BASE_URL + Constants.POST_UPDATE_CHAT_MSG_URL, jsonStr, MyHttp.POST, context, new SimplePaserJsonCallback() {
//            @Override
//            public void onVerifyIsNull() {
//                //TODO 删除待上传数据
//            deleteDB(mMsg,0);
//
//            }
//
//            @Override
//            public void onVerifySuccess(String dataRaw, boolean isCache) {
//
//            }
//        }, new HttpFailCallback() {
//            @Override
//            public void onServiceErrorCallback() {
//
//            }
//        });
//    }

    /**
     * 将环信消息生成我们的消息
     * @param message 环信消息
     * @param status
     * @return
     */
    private ChatMsgBean createMyMsg(EMMessage message, int status, int msgdir){

        int type = 0;
        String typename = "";
        EMMessage.Type mType = message.getType();
        switch (mType){
            case TXT:
                type = 1;
                typename = mType.name();
                break;
        }
        //msgBody
        EMMessageBody msgbody = message.getBody();
        String body = msgbody.toString();
        MyLog.d(TAG,"body: "+body);
        String subStr = body.substring(5, body.length()-1);
        //msgtime
        long msgtime = message.getMsgTime();
        //msgId
        String msgid = message.getMsgId();
        //username
        String username = message.getUserName();
        //isAsked
        int isasked = (message.isAcked() ? 1:0);
        //isdelivered
        int isdelivered = (message.isDelivered() ? 1:0);
        //islistened
        int islistened = (message.isListened() ? 1:0);
        // TODO   此处设置用户id
        int userid = CacheUtils.getIntData(context,Constants.LOGIN_UID,0);
        User user = UserDaoImpl.getIntance(context).findByQuery(userid);
        ChatMsgBean msgBean = ChatMsgBean.getTextMsg(userid,typename,user.easemobsaccount,subStr,status,type,msgtime,msgid,msgdir,username,isasked,isdelivered,islistened);
        return msgBean;
    }
    /**
     * 发送文本消息
     * @param content
     */
    public void sendTextMsg(String content) {
        //创建一条文本消息，content为消息文字内容，toChatUsername为对方用户或者群聊的id，后文皆是如此
        final EMMessage emMessage = EMMessage.createTxtSendMessage(content, toChatUsername);
        //生成一条自已的消息
        final ChatMsgBean myMsg = createMyMsg(emMessage,ChatMsgBean.MSG_STATUS_SENDING,ChatMsgBean.SELF);
        insertOrUpdateDB(myMsg,1);
        //生成用于展示的消息
        if(sendMesgCallback != null){
            sendMesgCallback.createMsgCallback(myMsg);
        }
        emMessage.setMessageStatusCallback(new EMCallBack() {
            @Override
            public void onSuccess() {
                myMsg.setStatus(ChatMsgBean.MSG_STATUS_SEND_SUCCESS);
                insertOrUpdateDB(myMsg,1);
//                updateMsgs(getMessages(myMsg),1);
                //TODO
                if(sendMesgCallback != null){
                    sendMesgCallback.onSendStatusChanged(myMsg);
                }
            }

            @Override
            public void onError(int i, String s) {
                myMsg.setStatus(ChatMsgBean.MSG_STATUS_SEND_FAIL);
                insertOrUpdateDB(myMsg,1);
//                updateMsgs(getMessages(myMsg),1);
                //TODO
                if(sendMesgCallback != null){
                    MyLog.e(TAG,"发送失败回调  msgId: "+emMessage.getMsgId());
                    myMsg.setStatus(ChatMsgBean.MSG_STATUS_SEND_SUCCESS);
                    sendMesgCallback.onSendStatusChanged(myMsg);
                }
            }

            @Override
            public void onProgress(int i, String s) {

            }
        });
        //发送消息
        EMClient.getInstance().chatManager().sendMessage(emMessage);
//        updateMsgs(getMessages(myMsg),2);
        //TODO

    }

    /**
     * 批量上传消息到服务器,存在则更新，不存在则添加
     * @param messages
     */
    public void updateMsgs(List<ChatMsgBean> messages ,int origin) {
        if(messages == null ||messages.size() == 0){
            return;
        }

        MyLog.i(TAG,"--------------------updateMsg------------------------");
        String originStr="未知   ";
        switch (origin){
            case 1:
                originStr = "发送消息给环信回调  ";
                break;
            case 2:
                originStr = "发送消息 -> 上传到服务器  ";
                break;
            case 3:
                originStr = "重发消息给环回调";
                break;
            case 4:
                originStr = "重发消息给环信 -> 上传服务器";
                break;
            case 5:
                originStr = "接收到消息 -> 上传服务器";
                break;
        }
        MyLog.d(TAG, "操作源:  "+originStr+"  update  msgs ");
        String jsonStr = getArrayDataJson(messages);
        MyHttp.requestFromJson(Constants.BASE_URL+Constants.POST_UPDATE_CHAT_MSGS_URL, jsonStr, MyHttp.POST, context, new SimplePaserJsonCallback() {
            @Override
            public void onVerifyIsNull() {
                //TODO 删除待上传数据库
                MyLog.d(TAG,"--上传到服务器完成!");

                ChatMsgDaoImpl.getIntance(context).deleteAll();

            }

            @Override
            public void onVerifySuccess(String dataRaw, boolean isCache) {

            }

            @Override
            public void onErrorCodeError(BaseEntity.MyError mError) {
                MyLog.e(TAG,"上传到服务器错误!");
            }
        }, new HttpFailCallback() {
            @Override
            public void onServiceErrorCallback() {

            }
        });
    }

    /**
     *  注册消息监听
     */
    private void registerMessageListener(){
        EMClient.getInstance().chatManager().addMessageListener(msgListener);
    }

    /**
     * 移除消息监听
     */
    private void removeMessageListener(){
        EMClient.getInstance().chatManager().removeMessageListener(msgListener);
    }

    /**
     * 收消息的监听
     */
    EMMessageListener msgListener = new EMMessageListener() {

        @Override
        public void onMessageReceived(List<EMMessage> messages) {
            //注:未读的消息包含发送的消息
            //收到消息
            EMConversation conversation = EMClient.getInstance().chatManager().getConversation(toChatUsername);
            EMMessage lastMsg = conversation.getLastMessage();

            int pagesize = conversation.getUnreadMsgCount();
            MyLog.i(TAG,"未读消息的条数: "+pagesize);
            //SDK初始化加载的聊天记录为20条，到顶时需要去DB里获取更多
            //获取startMsgId之前的pagesize条消息，此方法获取的messages SDK会自动存入到此会话中，APP中无需再次把获取到的messages添加到会话中
            MyLog.d(TAG,"最后一条消息     msgid: "+lastMsg.getMsgId()+"    消息内容: "+lastMsg.getBody() + "----此消息为接收,将消息存入服务器");
            List<EMMessage> moremessages = conversation.loadMoreMsgFromDB(lastMsg.getMsgId(), pagesize);
            List<EMMessage> uploadMessages;
            List<ChatMsgBean> mUploadMsg;
            mUploadMsg = new ArrayList<>();
            uploadMessages = new ArrayList<>();
            int size ;
            for(int i =0;i< moremessages.size()-1;i++){
                EMMessage currMsg;
                if(pagesize > 1){ //离线大于两条时就会将上一最后一次已读的消息读出来
                    currMsg = moremessages.get(i+1);
                }else{
                    currMsg = moremessages.get(i);
                }
                EMMessage.Direct direct = currMsg.direct();
                switch(direct){
                    case SEND:
                        MyLog.e(TAG,"未读消息的     msgid: "+currMsg.getMsgId()+"    消息内容: "+currMsg.getBody() + "此消息为发送,不需要重生成新消息");
                        break;
                    case RECEIVE:
                        MyLog.d(TAG,"未读消息的     msgid: "+currMsg.getMsgId()+"    消息内容: "+currMsg.getBody() + "----此消息为接收,将消息存入服务器");
                        uploadMessages.add(currMsg);
                        break;
                }

            }
            uploadMessages.add(lastMsg);
            for(int i =0;i<uploadMessages.size();i++){//展示未读消息
                if(sendMesgCallback != null){
                    ChatMsgBean myMsg = createMyMsg(uploadMessages.get(i), ChatMsgBean.MSG_STATUS_SEND_SUCCESS, ChatMsgBean.FROM);
                    sendMesgCallback.createMsgCallback(myMsg);
                    mUploadMsg.add(myMsg);
                    // TODO 存入上待上传数据库
                    //如果没有在聊天界面的处理

                    if(!isChatIsForegound()){
                        //1.存入未读数据库
                        //2.发送通知,增加红点
                        NewMsgCountDaoImpl.getIntance(context).insert(new NewMsgCountBean(myMsg.getMsgdir(),myMsg.getMsgid(),myMsg.getChatid()));
                        UIObserver.getInstance().hasNewMes(new MessageCountBean());
                    }
                    insertOrUpdateDB(myMsg,3);
                }
            }
            //设置消息为已读
            EMClient.getInstance().chatManager().markAllConversationsAsRead();
            //TODO
//            updateMsgs(mUploadMsg,5);
            //2. 批量上传数据(批量上传)
        }

        @Override
        public void onCmdMessageReceived(List<EMMessage> messages) {
            //收到透传消息
        }

        @Override
        public void onMessageRead(List<EMMessage> list) {

        }

        @Override
        public void onMessageDelivered(List<EMMessage> list) {

        }

        @Override
        public void onMessageChanged(EMMessage message, Object change) {
            //消息状态变动
        }
    };

    /**
     * 将lists生成 JSON 数组
     * @param lists
     * @return
     */
    private String getArrayDataJson(List<ChatMsgBean> lists){
        Gson gson = new Gson();
        return gson.toJsonTree(lists).toString();

    }

    /**
     * 登录环信
     * @param username  用户名
     * @param pwd 密码
     */
    public void login(final String username, final String pwd) {

        MyLog.d(TAG,"username = "+username+"   pwd = "+pwd);
        EMClient.getInstance().login(username, pwd, new EMCallBack() {

            @Override
            public void onSuccess() {
                EMClient.getInstance().groupManager().loadAllGroups();
                EMClient.getInstance().chatManager().loadAllConversations();
                MyLog.i(TAG, "登陆聊天服务器成功！");

            }

            @Override
            public void onProgress(int arg0, String arg1) {

            }

            @Override
            public void onError(int arg0, String arg1) {

                MyLog.e(TAG, "login error   string = "+arg1+ "   code = " +arg0 );
                //判断是否登录
                if(arg0 == 200){

                }else{
                    login(username,pwd);
                }
            }
        });
    }

    public void setSendMesgCallback(SendMesgCallback sendMesgCallback){
        this.sendMesgCallback = sendMesgCallback;
    }
    private SendMesgCallback sendMesgCallback;
    public interface SendMesgCallback{

        void onSendStatusChanged(ChatMsgBean message);

        /**
         * 生成发头消息的回调
         * @param message
         */
        void createMsgCallback(ChatMsgBean message);

    }

    /**
     * 重发消息
     * @param message
     */
    public void reSendTextMsg(final ChatMsgBean message){

        insertOrUpdateDB(message,2);
        //创建一条文本消息，content为消息文字内容，toChatUsername为对方用户或者群聊的id，后文皆是如此
        final EMMessage emMessage = EMMessage.createTxtSendMessage(message.getTextmsg(), toChatUsername);
        //将新消息的id给未发送成功的消息
        message.setMsgid(emMessage.getMsgId());//更新自定义消息的id
        emMessage.setMessageStatusCallback(new EMCallBack() {
            @Override
            public void onSuccess() {
                message.setStatus(ChatMsgBean.MSG_STATUS_SEND_SUCCESS);
                insertOrUpdateDB(message,2);
                //TODO
//                updateMsgs(getMessages(message),3);

                if(sendMesgCallback != null){
                    MyLog.i(TAG,"发送成功回调  msgId: "+emMessage.getMsgId());
                    sendMesgCallback.onSendStatusChanged(message);
                }
            }

            @Override
            public void onError(int i, String s) {
                message.setStatus(ChatMsgBean.MSG_STATUS_SEND_FAIL);
                insertOrUpdateDB(message,2);
                //TODO
//                updateMsgs(getMessages(message),3);

                if(sendMesgCallback != null){
                    MyLog.e(TAG,"发送失败回调  msgId: "+emMessage.getMsgId());
                    message.setStatus(ChatMsgBean.MSG_STATUS_SEND_SUCCESS);
                    sendMesgCallback.onSendStatusChanged(message);
                }
            }

            @Override
            public void onProgress(int i, String s) {

            }
        });
        //发送消息
        EMClient.getInstance().chatManager().sendMessage(emMessage);
        //TODO
//        updateMsgs(getMessages(message),4);

    }

    /**
     * 添加或更新数据库
     * @param myMsg  自定义消息
     * @param origin  来源  1  发送消息  2 重发消息  3 接收消息
     */
    private void insertOrUpdateDB(ChatMsgBean myMsg, int origin){

        MyLog.d(TAG,"<<<<<<<<<<<<<<<<<<<添加或更新数据库<<<<<<<<<<<<<<<<<<<<<<");
        ChatMsgDaoImpl chatMsgDao = ChatMsgDaoImpl.getIntance(context);
        //1.判断消息是否存在
        //2.存在则修改
        //3.不存在则添加
        boolean exists = chatMsgDao.isExists(myMsg.getChatid());
        if(!exists){
            //不存在,添加
            chatMsgDao.insert(myMsg);
        }else{
            //存在,更新
            ChatMsgBean oldMsg = chatMsgDao.findByQuery(myMsg.getChatid());
            myMsg.setId(oldMsg.getId());
            chatMsgDao.updata(myMsg);
        }
        List<ChatMsgBean> all = chatMsgDao.findAll();
        String originStr="";
        switch (origin){
            case 1:
                originStr = "发送消息  ";
                break;
            case 2:
                originStr = "重发消息  ";
                break;
            case 3:
                originStr = "接收消息  ";
                break;
        }
        MyLog.d(TAG, "操作源:  "+originStr+"  add or update cache msg size: "+all.size()+"  mymsgid: "+ myMsg.getChatid());
    }

    /**
     * 删除数据库
     * @param myMsg  自定义消息
     * @param origin  来源  1  发送消息  2 重发消息  3 接收消息
     */
    private void deleteDB(ChatMsgBean myMsg,int origin){

        MyLog.d(TAG,">>>>>>>>>>>>>>>>>>>删除数据库>>>>>>>>>>>>>>>>>>>>");
        String originStr="未知   ";
        switch (origin){
            case 1:
                originStr = "发送消息  ";
                break;
            case 2:
                originStr = "重发消息  ";
                break;
            case 3:
                originStr = "接收消息  ";
                break;
        }

        ChatMsgBean byQuery = ChatMsgDaoImpl.getIntance(context).findByQuery(myMsg.getChatid());
        if(byQuery != null){
            ChatMsgDaoImpl.getIntance(context).delete(byQuery.getId());
            List<ChatMsgBean> all = ChatMsgDaoImpl.getIntance(context).findAll();
            MyLog.i(TAG, "操作源:  "+originStr+"  delete  cache msg size: "+all.size()+"  mymsgid: "+ myMsg.getChatid());
        }else{
            MyLog.e(TAG,"操作源:  "+originStr+"删除消息失败,  mymsgid: "+myMsg.getChatid());
        }
    }

    /**
     * 生成消息list
     * @param myMsg
     * @return
     */
    private List<ChatMsgBean> getMessages(ChatMsgBean myMsg){

        List<ChatMsgBean> messages = new ArrayList<>();
        if(myMsg != null){
            messages.add(myMsg);
        }
        return messages;
    }
}
